from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

# 生成支付链接
from course.models import Course
from payment.models import Orders
from payment.utils import get_order_id
from syl import settings
from user.models import Vip
from alipay import AliPay
from syl.settings import BASE_DIR
import os
import datetime

app_private_key_string = open(os.path.join(BASE_DIR, "apps/payment/keys/app_private_key.pem")).read()
alipay_public_key_string = open(os.path.join(BASE_DIR, "apps/payment/keys/alipay_public_key.pem")).read()


class PayMentAPIView(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request):
        # 1. 参数:　user,type, (vip_id|course_id),
        user = request.user
        type = request.data.get('type')  # 1. vip,   2. course
        gid = request.data.get('gid')  # vip_id|course_id

        if all([type, gid]):
            pass
        else:
            return Response({'code': '999', 'msg': '缺少参数'})
        # 2. 准备数据
        # 2.1 order_id
        order_id = get_order_id()
        # 2.2 amount  金额
        # 2.3 subject  生成链接用, 商品名  vip名字,  或者 课程名字
        # (1, 'vip'),(2, 'course')
        if type == '1':
            # 根据vip取价格
            try:
                goods = Vip.objects.get(id=gid)
            except Exception as e:
                return Response({'code': '999', 'msg': '商品不存在'})
            # 2.2 amount  金额
            amount = goods.price
            # 2.3 subject  生成链接用, 商品名  vip名字,  或者 课程名字
            subject = goods.desc
            # 3. 保存订单
            order = Orders.objects.create(
                user=user,
                type=type,
                vip=goods,
                order_id=order_id,
                amount=amount
            )
        else:
            # 根据训练营取价格
            try:
                goods = Course.objects.get(id=gid)
            except Exception as e:
                return Response({'code': '999', 'msg': '商品不存在'})
            # 2.2 amount  金额
            amount = goods.price
            # 2.3 subject  生成链接用, 商品名  vip名字,  或者 课程名字
            subject = goods.title
            # 3. 保存订单
            order = Orders.objects.create(
                user=user,
                type=type,
                course=goods,
                order_id=order_id,
                amount=amount
            )

        # 4. 生成支付链接
        alipay = AliPay(
            appid=settings.ALIPAY_APP_ID,
            app_notify_url=None,  # 后台通知地址
            app_private_key_string=app_private_key_string,
            # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            alipay_public_key_string=alipay_public_key_string,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG,  # 默认False
        )

        # 电脑网站支付，需要跳转到https://openapi.alipay.com/gateway.do? + order_string
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order.order_id,  # syl订单号
            total_amount=float(order.amount),  # 金额
            subject=subject,  # 商品名
            return_url=settings.ALIPAY_CALLBACK,
        )

        pay_url = settings.ALIPAY_GATEWAY + order_string

        # 5. 返回支付链接
        return Response({'code': '0', 'msg': 'ok', 'pay_url': pay_url})


'''
charset=utf-8  编码方式
&out_trade_no=SYL20201261018355953269  订单号
&method=alipay.trade.page.pay.return   支付方式
&total_amount=299.00  金额
&sign=gHHdyVf0ZExxOsnudbYNE75IPEJhWCyUvkpolMlbmz6UQZEk2fjXDteYHrEweJv7pOx7ZJDkv94BQQHUJtZg%2Fqr7fYHe1S1KwDl2vH0QYSerEwXG0HiCnZzpO52SYmOh83ubrzbnLYlI6ir4%2Be2588dmgCjObpqGKVvrGMcgc5%2FnEK0JMmhW1u5V28ZDOGIlmqjjxLANGb0INsLQdPrGzJax8ad9u9bBCgZlmiByoUB1MuGYAEcjd4HKSeASpOAvQyLhRbiuYlwpNcvzN2ZRFuXKSbPLFm3Ffkrr4hyQAFaa4%2Fk6VMQTv0CD%2BhtFMvxGW4M%2FaaeMMEYDYChgeoUG0Q%3D%3D  签名
&trade_no=2020120622001401170502794664   支付宝订单号
&auth_app_id=2016110100784529   支付宝开放平台id
&version=1.0
&app_id=2016110100784529  支付宝开放平台id
&sign_type=RSA2   加密方式
&seller_id=2088102181603431  卖方id
&timestamp=2020-12-06%2010%3A19%3A40  支付时间
'''


class PayMentCallBackAPIView(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request):
        # 1. 接收参数, 接收一坨,   原始数据 => 签名sign
        data = request.data.get('query')
        # 2. 校验一下签名对不对
        # 2.1 生成支付宝对象, 这个对象中, 可以生成支付链接, 可以校验签名
        alipay = AliPay(
            appid=settings.ALIPAY_APP_ID,
            app_notify_url=None,  # 后台通知地址
            app_private_key_string=app_private_key_string,
            # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            alipay_public_key_string=alipay_public_key_string,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG,  # 默认False
        )
        # 2.2 从全部数据中, 分离出 sign , 和原始数据, 使用一个方法,  传入, 原始数据 => 新sign, 和支付宝sign,
        sign = data.pop('sign')
        result = alipay.verify(data, sign)
        if result:
            pass
        else:
            return Response({'code': '999', 'msg': '非法请求'})

        # 3. 如果校验正确, 那么说明, 支付成功,
        # 3.0 获取订单,   先获取订单号, 然后, 更新订单,
        order_id = data.get('out_trade_no')
        order = Orders.objects.get(order_id=order_id)
        if order.alipay_order_id:
            order_data = {
                'order_id': order.order_id,  # 订单号
                'amount': order.amount,  # 金额
                'subject': order.subject,  # 购买商品
                'time': order.pay_time,  # 支付时间
            }
            return Response({'code': '0', 'msg': '订单已处理', 'order': order_data})
        alipay_trade_no = data.get('trade_no')
        pay_time = data.get('timestamp')
        # 3.0.0 更新订单
        order.alipay_order_id = alipay_trade_no
        order.pay_time = pay_time
        order.save()

        # 3.1. 给用户设置vip
        if order.type == 1:
            # vip
            user = order.user
            vip = order.vip
            user.vip = vip
            now_datetime = datetime.datetime.now()  # 年月日时分秒
            now_date = now_datetime.date()  # 年月日

            tianshu = vip.duration  # 天数
            # 时间段
            shijianduan = datetime.timedelta(days=tianshu)
            vip_exp = now_date + shijianduan
            user.vip_exp = vip_exp
            user.save()
            pass
        elif order.type == 2:
            # course
            # 3.2. 给用户购买的课程关系表, 增加购买课程
            pass
        else:
            return Response({'code': '999', 'msg': '信息有误'})

        # 4. 返回结果
        order_data = {
            'order_id': order.order_id,  # 订单号
            'amount': order.amount,  # 金额
            'subject': order.subject,  # 购买商品
            'time': order.pay_time,  # 支付时间
        }
        return Response({'code': '0', 'msg': '购买成功', 'order': order_data})
